package com.heima.article.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.wemedia.dtos.ChannelDto;
import io.netty.channel.pool.ChannelHealthChecker;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zzy
 * @date 2022/7/29 15:08
 */

@Service
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private CacheService cacheService;

    @Override
    public void computeHotArticle() {

        //查询五天内的发布的文章
        //当前时间的前五天
        LocalDateTime localDateTime = LocalDateTime.now().minusDays(5);
        List<ApArticle> list = apArticleMapper.findArticleListByLast5days(localDateTime);
        if (CollectionUtils.isEmpty(list)) {
            log.warn("近五天没有文章");
            return;
        }

        //计算集合中所有文章的总热度 工具类
        List<HotArticleVo> compute = compute(list);

        //分组HuToll
        List<List<HotArticleVo>> lists = CollectionUtil.groupByField(compute, "channelId");
        //分组HuToll
        //取前30条记录
        //写入到Redis
        //遍历分组之后的结果    工具类
        if (CollectionUtils.isEmpty(lists)) {
            log.warn("分组的数据为空");
            return;
        }
        for (List<HotArticleVo> hotArticleVos : lists) {
            if (hotArticleVos == null) {
                continue;
            }
            Integer channelId = hotArticleVos.get(0).getChannelId();

            sortAndCaching(hotArticleVos, channelId.toString());
        }
        //推荐频道计算和处理
        sortAndCaching(compute, ArticleConstants.DEFAULT_TAG);

    }

    //分组HuToll
    //取前30条记录
    //写入到Redis
    private void sortAndCaching(List<HotArticleVo> voList, String channelId) {
        //排序 stream.sort
        voList = voList.stream().sorted(new Comparator<HotArticleVo>() {
            @Override
            public int compare(HotArticleVo o1, HotArticleVo o2) {
                Integer score1 = o1.getScore();
                Integer score = o2.getScore();
                return score1 - score;
            }
        }).collect(Collectors.toList());
        //取前30条记录  subList(0, 30)
        if (voList.size() > 30) {
            voList = voList.subList(0, 30);
        }

        //写入到Redis  String类型
        cacheService.set(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + channelId, JSON.toJSONString(voList));

    }


    //计算集合中所有文章的总热度
    private List<HotArticleVo> compute(List<ApArticle> list) {
        //遍历上面那个集合 阅读 点赞 评论 收藏
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        List<HotArticleVo> resultList = new ArrayList<>();
        for (ApArticle apArticle : list) {
            if (apArticle == null) {
                continue;
            }
            //计算集合中所有文章的总热度
            Integer score = 0;
            Integer views = apArticle.getViews();
            Integer likes = apArticle.getLikes();
            Integer comment = apArticle.getComment();
            Integer collection = apArticle.getCollection();
            if (views != null) {
                score += views;
            }
            if (likes != null) {
                score += likes * 3;
            }
            if (comment != null) {
                score += comment * 5;
            }
            if (collection != null) {
                score += collection * 8;
            }

            HotArticleVo vo = new HotArticleVo();
            vo.setScore(score);
            BeanUtils.copyProperties(apArticle, vo);
            resultList.add(vo);

        }
        return resultList;
    }
}
